package com.lenovo.lcdm.dcm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.lenovo.lcdm.dcm.common.util.ContextUtil;
import com.lenovo.lcdm.dcm.constant.DcmConstant;
import com.lenovo.lcdm.dcm.dto.CtoCVsDto;
import com.lenovo.lcdm.dcm.entity.ConfigurationGeoCountryMapping;
import com.lenovo.lcdm.dcm.entity.ConfigurationGeoMapping;
import com.lenovo.lcdm.dcm.entity.CtoCV;
import com.lenovo.lcdm.dcm.entity.DcmBusinessConfigurationCategoryC;
import com.lenovo.lcdm.dcm.mapper.CtoCVMapper;
import com.lenovo.lcdm.dcm.service.ConfigurationGeoCountryMappingService;
import com.lenovo.lcdm.dcm.service.ConfigurationGeoMappingService;
import com.lenovo.lcdm.dcm.service.CtoCVService;
import com.lenovo.lcdm.dcm.service.DcmBusinessConfigurationCategoryCService;
import com.lenovo.lcdm.team.dto.UserAuthDto;
import com.lenovo.lcdm.team.entity.TeamGroup;
import com.lenovo.lcdm.team.service.ITeamUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sunby1
 * @description 针对表【integration_cto_c_v】的数据库操作Service实现
 * @createDate 2024-02-02 15:40:48
 */
@Service
public class CtoCVServiceImpl extends ServiceImpl<CtoCVMapper, CtoCV>
        implements CtoCVService {

    private final DcmBusinessConfigurationCategoryCService dcmBusinessConfigurationCategoryCService;
    private final ConfigurationGeoCountryMappingService configurationGeoCountryMappingService;
    private final ConfigurationGeoMappingService configurationGeoMappingService;
    private final ITeamUserService iTeamUserService;

    @Autowired
    public CtoCVServiceImpl(DcmBusinessConfigurationCategoryCService dcmBusinessConfigurationCategoryCService,
                            ConfigurationGeoCountryMappingService configurationGeoCountryMappingService,
                            ConfigurationGeoMappingService configurationGeoMappingService,
                            ITeamUserService iTeamUserService) {
        this.dcmBusinessConfigurationCategoryCService = dcmBusinessConfigurationCategoryCService;
        this.configurationGeoCountryMappingService = configurationGeoCountryMappingService;
        this.configurationGeoMappingService = configurationGeoMappingService;
        this.iTeamUserService = iTeamUserService;
    }

    @Override
    public List<CtoCVsDto> getCVsByCtoName(String ctoName) {
        List<CtoCV> ctoCVS = lambdaQuery().in(CtoCV::getCtoNumber, Arrays.stream(ctoName.split(",")).toList()).list();
        if (CollectionUtil.isNotEmpty(ctoCVS)) {
            Map<String, List<CtoCV>> map = ctoCVS.stream().collect(Collectors.groupingBy(CtoCV::getCharname));
            return map.keySet().stream().map(key -> {
                CtoCVsDto ctoCVsDto = new CtoCVsDto();
                ctoCVsDto.setCategory(key);
                ctoCVsDto.setValues(map.get(key).stream().map(CtoCV::getValue).toList());
                return ctoCVsDto;
            }).toList();
        }
        return null;
    }

    @Override
    public List<String> getByMachineType(String machineType) {
        List<CtoCV> ctoCVS = lambdaQuery().likeRight(CtoCV::getCtoNumber, machineType).list();
        return ctoCVS.stream().map(CtoCV::getCtoNumber).distinct().toList();
    }

    @Override
    public List<CtoCVsDto> getCVListByCtoNamesAndProductSegment(String ctoNumbers, String productSegment, String geo) {
        List<CtoCV> ctoCVS = lambdaQuery().in(CtoCV::getCtoNumber, Arrays.stream(ctoNumbers.split(",")).toList()).list();
        List<DcmBusinessConfigurationCategoryC> categoryCServiceList = dcmBusinessConfigurationCategoryCService.getAll();
        List<ConfigurationGeoCountryMapping> geoCountryMappingList = configurationGeoCountryMappingService.list();

        // 获取categoryCMapping
        List<CtoCVsDto> result = Lists.newArrayList();
        List<DcmBusinessConfigurationCategoryC> categoryCServiceAll = categoryCServiceList.stream()
                .filter(category -> category.getNbDt().equals(productSegment))
                .toList();

        // 获取getCountryMapping
        geoCountryMappingList = geoCountryMappingList.stream()
                .peek(mapping -> {
                    if (!mapping.getCountrySuffix().startsWith("_")) {
                        mapping.setCountrySuffix("_" + mapping.getCountrySuffix());
                    }
                }).toList();

        Map<String, List<String>> suffixFullMap = geoCountryMappingList.stream()
                .filter(item -> StringUtils.isBlank(item.getGeo()))
                .collect(Collectors.groupingBy(ConfigurationGeoCountryMapping::getCategory, Collectors.mapping(ConfigurationGeoCountryMapping::getCountrySuffix, Collectors.toList())));

        Map<String, List<String>> suffixMap = geoCountryMappingList.stream()
                .filter(item -> geo.equals(item.getGeo()))
                .collect(Collectors.groupingBy(ConfigurationGeoCountryMapping::getCategory, Collectors.mapping(ConfigurationGeoCountryMapping::getCountrySuffix, Collectors.toList())));

        ctoCVS.stream().collect(Collectors.groupingBy(CtoCV::getCharname)).forEach((key, values) -> {
            List<DcmBusinessConfigurationCategoryC> dcmBusinessConfigurationCategoryCS = categoryCServiceAll.stream()
                    .filter(category -> Arrays.stream(category.getCharacteristic().split(",")).toList().contains(key))
                    .toList();
            if (CollectionUtil.isNotEmpty(dcmBusinessConfigurationCategoryCS)) {
                values.stream().collect(Collectors.groupingBy(CtoCV::getCtoNumber)).forEach((cto, values1) -> {
                    CtoCVsDto ctoCVsDto = new CtoCVsDto();
                    ctoCVsDto.setCtoNumber(cto);
                    ctoCVsDto.setCharname(key);
                    ctoCVsDto.setCategory(dcmBusinessConfigurationCategoryCS.get(0).getCategory());
                    List<String> allCountries = suffixFullMap.get(dcmBusinessConfigurationCategoryCS.get(0).getCategory());
                    List<String> countries = suffixMap.get(dcmBusinessConfigurationCategoryCS.get(0).getCategory());
                    List<String> filterValue = values1.stream()
                            .map(cv -> Arrays.stream(cv.getValue().split(",")).toList())
                            .flatMap(List::stream)
                            .distinct()
                            .filter(value -> {
                                if (CollectionUtil.isEmpty(allCountries) || allCountries.stream().noneMatch(value::endsWith)) {
                                    return true;
                                }
                                if (allCountries.stream().anyMatch(value::endsWith)) {
                                    List<String> list = allCountries.stream().filter(value::endsWith).toList();
                                    Optional<String> max = list.stream().max(Comparator.comparing(String::length));
                                    if (max.isPresent()) {
                                        String country = max.get();
                                        return CollectionUtil.isNotEmpty(countries) && new HashSet<>(countries).contains(country);
                                    }
                                }
                                return false;
                            }).toList();
                    ctoCVsDto.setValues(filterValue);
                    result.add(ctoCVsDto);
                });
            }
        });
        return result;
    }

    private List<String> getGeos() {
        UserAuthDto userAuthorities = iTeamUserService.getUserAuthorities(ContextUtil.getCurrentUser(), false);
        List<ConfigurationGeoMapping> list = configurationGeoMappingService.list();
        List<TeamGroup> groups = userAuthorities.getGroups();
        List<String> geos = Lists.newArrayList(list.stream()
                .filter(geoMapping -> groups.stream().map(TeamGroup::getGroupName).toList().contains(geoMapping.getGroupName()))
                .map(ConfigurationGeoMapping::getGeo).toList());
        if (CollectionUtil.isEmpty(geos)) {
            geos.addAll(Lists.newArrayList(Arrays.stream(DcmConstant.GEO).toList()));
        }
        return geos;
    }
}




